package org.szgb.console.nlms.iams.service;

import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
import io.minio.MinioClient;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.szgb.console.config.MinIOInfo;
import org.szgb.console.nlms.user.entity.NlmsUser;
import org.szgb.console.nlms.user.mapper.NlmsUserMapper;
import org.szgb.console.sys.file.entity.SysFile;
import org.szgb.console.sys.file.mapper.SysFileMapper;
import org.szgb.console.sys.user.entity.SysUser;
import org.szgb.console.sys.user.mapper.SysUserMapper;
import org.szgb.console.utils.UUIDUtil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class NlmsIamsService {
    private final HttpClient httpClient;
    private final NlmsUserMapper nlmsUserMapper;
    private final SysUserMapper sysUserMapper;
    private final SysFileMapper sysFileMapper;
    private final MinioClient minioClient;
    private final MinIOInfo minIOInfo;

    @Value("${nlms.iams-api}")
    private String iamsApi;

    public NlmsIamsService(HttpClient httpClient, NlmsUserMapper nlmsUserMapper, SysUserMapper sysUserMapper, SysFileMapper sysFileMapper, MinioClient minioClient, MinIOInfo minIOInfo) {
        this.httpClient = httpClient;
        this.nlmsUserMapper = nlmsUserMapper;
        this.sysUserMapper = sysUserMapper;
        this.sysFileMapper = sysFileMapper;
        this.minioClient = minioClient;
        this.minIOInfo = minIOInfo;
    }

    @Transactional
    public String loginIams(String userId) throws IOException, InterruptedException {
        SysUser sysUser = sysUserMapper.get(userId);
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        if (nlmsUser == null) {
            nlmsUser = new NlmsUser();
            // 对于新实体，设置创建者信息
            nlmsUser.setUpdatedBy(sysUser);
            nlmsUser.setCreatedBy(sysUser);
            // 添加UUID
            nlmsUser.setId(UUIDUtil.getUUID());
            nlmsUser.setSysUser(sysUser);
            nlmsUserMapper.insert(nlmsUser);
        }
        String url = iamsApi + "/login/nlms/" + sysUser.getUsername() + "1F631xm6T8ia6B5rb7iamspu7E583Hs8Ljd9amtrD5L3/04/2";
        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
                .header("Accept-Encoding", "gzip, deflate")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("Upgrade-Insecure-Requests", "1")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0")
                .GET();
        if (nlmsUser.getMainSessionId() != null) {
            builder.setHeader("Cookie", "MAINSESSIONID=" + nlmsUser.getMainSessionId());
        }
        HttpRequest request = builder.build();
        HttpResponse<String> response = httpClient.send(request,
                HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 302) {
            List<String> strings = response.headers().allValues("set-cookie");
            for (String string : strings) {
                for (String s : string.split(";")) {
                    String[] split = s.split("=");
                    if (split[0].equals("MAINSESSIONID")) {
                        nlmsUser.setMainSessionId(split[1]);
                        nlmsUserMapper.update(nlmsUser);
                    }
                }
            }
        }

        if (response.statusCode() != 200 && response.statusCode() != 201 && response.statusCode() != 302) {
            throw new RuntimeException("HTTP请求失败: " + response.statusCode());
        }
        return nlmsUser.getMainSessionId();
    }

    @Transactional
    public String getAddProblemForm(String userId) throws IOException, InterruptedException {
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        String mainSessionId;
        if (nlmsUser == null || nlmsUser.getMainSessionId() == null) {
            mainSessionId = this.loginIams(userId);
        } else {
            mainSessionId = nlmsUser.getMainSessionId();
        }
        String url = iamsApi + "/problem/problem/input/add";
        // 保持 GET，但修复其他问题
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.7345.88 Safari/537.36")
                .header("Referer", iamsApi + "/business/add/problem?taskId=add")
                .header("Cookie", "loginUrl=https://nlms.xmgdjt.com.cn:6001; MAINSESSIONID=" + mainSessionId)
                .header("upgrade-insecure-requests","1")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    @Transactional
    public String getProfession(String userId) throws IOException, InterruptedException {
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        String mainSessionId;
        if (nlmsUser == null || nlmsUser.getMainSessionId() == null) {
            mainSessionId = this.loginIams(userId);
        } else {
            mainSessionId = nlmsUser.getMainSessionId();
        }
        String url = iamsApi + "/basicdata/item/query-tree";
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "application/json, text/javascript, */*; q=0.01")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.7345.88 Safari/537.36")
                .header("Referer", iamsApi + "/business/add/problem?taskId=add")
                .header("Cookie", "loginUrl=https://nlms.xmgdjt.com.cn:6001; MAINSESSIONID=" + mainSessionId)
                .header("x-requested-with", "XMLHttpRequest")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    @Transactional
    public String getLocation(String userId, String station) throws IOException, InterruptedException {
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        String mainSessionId;
        if (nlmsUser == null || nlmsUser.getMainSessionId() == null) {
            mainSessionId = this.loginIams(userId);
        } else {
            mainSessionId = nlmsUser.getMainSessionId();
        }
        String url = iamsApi + "/basicdata/position/by-stationType?stationType=" + station + "&stationType=" + station;
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "application/json, text/javascript, */*; q=0.01")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.7345.88 Safari/537.36")
                .header("Referer", iamsApi + "/problem/problem/input/add")
                .header("Cookie", "loginUrl=https://nlms.xmgdjt.com.cn:6001; MAINSESSIONID=" + mainSessionId)
                .header("x-requested-with", "XMLHttpRequest")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    @Transactional
    public String multiupload(String userId, String fileId) throws IOException, InterruptedException,
            ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException,
            InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {

        // 1. 获取用户 Session
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        String mainSessionId = (nlmsUser != null && nlmsUser.getMainSessionId() != null)
                ? nlmsUser.getMainSessionId()
                : this.loginIams(userId);

        // 2. 获取文件信息
        SysFile sysFile = sysFileMapper.get(fileId);
        if (sysFile == null) {
            throw new IllegalArgumentException("文件不存在: " + fileId);
        }

        // 文件名
        String filename = sysFile.getName()+sysFile.getSubFix();
        if (filename.isEmpty()) {
            filename = sysFile.getName() + sysFile.getSubFix();
        }

        // 3. 从 MinIO 获取文件流
        GetObjectResponse objectResponse = minioClient.getObject(GetObjectArgs.builder()
                .bucket(minIOInfo.getBucketName())
                .object(sysFile.getId() + sysFile.getSubFix())
                .build());

        try (objectResponse) { // 自动关闭流
            // 4. 构建 multipart/form-data 请求体
            String boundary = "WebKitFormBoundary" + UUID.randomUUID().toString().substring(0, 8); // 不以 - 开头
            ByteArrayOutputStream requestBody = new ByteArrayOutputStream();

            // ✅ Part 1: 开始 boundary
            requestBody.write(("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8));

            // ✅ Part 2: 写入字段头（必须包含换行）
            requestBody.write(("Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\n").getBytes(StandardCharsets.UTF_8));

            // ✅ Part 3: 空行（关键！表示 header 结束）
            requestBody.write("\r\n".getBytes(StandardCharsets.UTF_8));

            // ✅ Part 4: 写入文件二进制内容
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = objectResponse.read(buffer)) != -1) {
                requestBody.write(buffer, 0, bytesRead);
            }

            // ✅ Part 5: 换行 + 结束 boundary
            requestBody.write("\r\n".getBytes(StandardCharsets.UTF_8));
            requestBody.write(("--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8));

            requestBody.close();

            // 5. 构建 HTTP 请求
            String url = iamsApi + "/zuul/file/annex/multiupload";
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .timeout(Duration.ofSeconds(30))
                    .header("Accept", "*/*")
                    .header("Content-Type", "multipart/form-data; boundary=" + boundary) // ✅ 使用同一 boundary
                    .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.7345.88 Safari/537.36")
                    .header("Referer", iamsApi + "/business/add/problem?taskId=add")
                    .header("Cookie", "loginUrl=https://nlms.xmgdjt.com.cn:6001; MAINSESSIONID=" + mainSessionId)
                    .header("X-Requested-With", "XMLHttpRequest")
                    .POST(HttpRequest.BodyPublishers.ofByteArray(requestBody.toByteArray()))
                    .build();

            // 6. 发送请求
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

            // 7. 返回响应
            return response.body();

        } catch (Exception e) {
            log.error("文件上传失败 [userId={}, fileId={}]", userId, fileId, e);
            throw e;
        }
    }

    @Transactional
    public String getClass(String userId,String professionId) throws IOException, InterruptedException {
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        String mainSessionId;
        if (nlmsUser == null || nlmsUser.getMainSessionId() == null) {
            mainSessionId = this.loginIams(userId);
        } else {
            mainSessionId = nlmsUser.getMainSessionId();
        }
        String url = iamsApi + "/problem/problem-classify/by-item?itemId=" + professionId + "&itemId=" + professionId;
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "application/json, text/javascript, */*; q=0.01")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.7345.88 Safari/537.36")
                .header("Referer", iamsApi + "/problem/problem/input/add")
                .header("Cookie", "loginUrl=https://nlms.xmgdjt.com.cn:6001; MAINSESSIONID=" + mainSessionId)
                .header("x-requested-with", "XMLHttpRequest")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    @Transactional
    public String getSecurity(String userId) throws IOException, InterruptedException {
        NlmsUser nlmsUser = nlmsUserMapper.getByUserId(userId);
        String mainSessionId;
        if (nlmsUser == null || nlmsUser.getMainSessionId() == null) {
            mainSessionId = this.loginIams(userId);
        } else {
            mainSessionId = nlmsUser.getMainSessionId();
        }
        String url = iamsApi + "/security/useunit/external/query-tree";
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "application/json, text/javascript, */*; q=0.01")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.7345.88 Safari/537.36")
                .header("Referer", iamsApi + "/common/external/tree-select?single=true&_=1757552953308")
                .header("Cookie", "loginUrl=https://nlms.xmgdjt.com.cn:6001; MAINSESSIONID=" + mainSessionId)
                .header("x-requested-with", "XMLHttpRequest")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }
}
